"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeLocalStateFlag = exports.addLocalStateFlag = exports.hasLocalStateFlag = exports.isConfigFlagEnabled = exports.updateDefaultCmsPublishMode = exports.updateAutoOpenBrowser = exports.updateAllowAutoUpdates = exports.updateAllowUsageTracking = exports.updateHttpTimeout = exports.removeAccountFromConfig = exports.renameConfigAccount = exports.setConfigAccountAsDefault = exports.updateConfigAccount = exports.addConfigAccount = exports.getConfigAccountEnvironment = exports.getAllConfigAccounts = exports.getConfigDefaultAccountIfExists = exports.getConfigDefaultAccount = exports.getConfigAccountIfExists = exports.getConfigAccountByName = exports.getConfigAccountById = exports.deleteConfigFileIfEmpty = exports.createEmptyConfigFile = exports.validateConfig = exports.getConfig = exports.getConfigFilePath = exports.configFileExists = exports.globalConfigFileExists = exports.localConfigFileExists = exports.getLocalConfigFilePathIfExists = exports.getGlobalConfigFilePath = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const findup_sync_1 = __importDefault(require("findup-sync"));
const config_1 = require("../constants/config");
const logger_1 = require("../lib/logger");
const utils_1 = require("./utils");
const files_1 = require("../constants/files");
const lang_1 = require("../utils/lang");
const defaultAccountOverride_1 = require("./defaultAccountOverride");
const environment_1 = require("../lib/environment");
const HubSpotConfigError_1 = require("../models/HubSpotConfigError");
const config_2 = require("../constants/config");
const isDeepEqual_1 = require("../lib/isDeepEqual");
const path_1 = require("../lib/path");
const EMPTY_CONFIG = { accounts: [] };
function getGlobalConfigFilePath() {
    return config_1.GLOBAL_CONFIG_PATH;
}
exports.getGlobalConfigFilePath = getGlobalConfigFilePath;
function getLocalConfigFilePathIfExists(cwd) {
    return (0, findup_sync_1.default)([
        config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME,
        config_1.DEFAULT_HUBSPOT_CONFIG_YAML_FILE_NAME.replace('.yml', '.yaml'),
    ], { cwd: cwd || (0, path_1.getCwd)() });
}
exports.getLocalConfigFilePathIfExists = getLocalConfigFilePathIfExists;
function localConfigFileExists() {
    return Boolean(getLocalConfigFilePathIfExists());
}
exports.localConfigFileExists = localConfigFileExists;
function globalConfigFileExists() {
    return (0, utils_1.doesConfigFileExistAtPath)(getGlobalConfigFilePath());
}
exports.globalConfigFileExists = globalConfigFileExists;
function configFileExists() {
    try {
        return (0, utils_1.doesConfigFileExistAtPath)(getConfigFilePath());
    }
    catch (error) {
        return false;
    }
}
exports.configFileExists = configFileExists;
function getConfigDefaultFilePath() {
    const globalConfigFilePath = getGlobalConfigFilePath();
    if ((0, utils_1.doesConfigFileExistAtPath)(globalConfigFilePath)) {
        return globalConfigFilePath;
    }
    const localConfigFilePath = getLocalConfigFilePathIfExists();
    if (!localConfigFilePath) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getDefaultConfigFilePath.error'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.CONFIG_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    return localConfigFilePath;
}
function getConfigFilePath() {
    const { configFilePathFromEnvironment } = (0, utils_1.getConfigPathEnvironmentVariables)();
    return configFilePathFromEnvironment || getConfigDefaultFilePath();
}
exports.getConfigFilePath = getConfigFilePath;
function getConfig() {
    let pathToRead;
    try {
        const { useEnvironmentConfig } = (0, utils_1.getConfigPathEnvironmentVariables)();
        if (useEnvironmentConfig) {
            return (0, utils_1.buildConfigFromEnvironment)();
        }
        pathToRead = getConfigFilePath();
        logger_1.logger.debug((0, lang_1.i18n)('config.getConfig.reading', { path: pathToRead }));
        const configFileSource = (0, utils_1.readConfigFile)(pathToRead);
        return (0, utils_1.parseConfig)(configFileSource, pathToRead);
    }
    catch (err) {
        throw new HubSpotConfigError_1.HubSpotConfigError(pathToRead
            ? (0, lang_1.i18n)('config.getConfig.errorWithPath', { path: pathToRead })
            : (0, lang_1.i18n)('config.getConfig.error'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.CONFIG_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ, { cause: err });
    }
}
exports.getConfig = getConfig;
function validateConfig() {
    const config = getConfig();
    if (config.accounts.length === 0) {
        return {
            isValid: false,
            errors: [(0, lang_1.i18n)('config.validateConfig.missingAccounts')],
        };
    }
    const accountIdsMap = {};
    const accountNamesMap = {};
    const validationErrors = [];
    config.accounts.forEach(account => {
        const accountValidationResult = (0, utils_1.validateConfigAccount)(account);
        if (!accountValidationResult.isValid) {
            validationErrors.push(...accountValidationResult.errors);
        }
        if (accountIdsMap[account.accountId]) {
            validationErrors.push((0, lang_1.i18n)('config.validateConfig.duplicateAccountIds', {
                accountId: account.accountId,
            }));
        }
        if (account.name) {
            if (accountNamesMap[account.name.toLowerCase()]) {
                validationErrors.push((0, lang_1.i18n)('config.validateConfig.duplicateAccountNames', {
                    accountName: account.name,
                }));
            }
            if (/\s+/.test(account.name)) {
                validationErrors.push((0, lang_1.i18n)('config.validateConfig.invalidAccountName', {
                    accountName: account.name,
                }));
            }
            accountNamesMap[account.name] = true;
        }
        accountIdsMap[account.accountId] = true;
    });
    return { isValid: validationErrors.length === 0, errors: validationErrors };
}
exports.validateConfig = validateConfig;
function createEmptyConfigFile(useGlobalConfig = false) {
    const { configFilePathFromEnvironment } = (0, utils_1.getConfigPathEnvironmentVariables)();
    const defaultPath = useGlobalConfig
        ? getGlobalConfigFilePath()
        : (0, utils_1.getLocalConfigDefaultFilePath)();
    const pathToWrite = configFilePathFromEnvironment || defaultPath;
    (0, utils_1.writeConfigFile)(EMPTY_CONFIG, pathToWrite);
}
exports.createEmptyConfigFile = createEmptyConfigFile;
function deleteConfigFileIfEmpty() {
    const pathToDelete = getConfigFilePath();
    try {
        const config = getConfig();
        if ((0, isDeepEqual_1.isDeepEqual)(config, EMPTY_CONFIG)) {
            fs_extra_1.default.unlinkSync(pathToDelete);
        }
    }
    catch (error) {
        const { message, type } = (0, utils_1.handleConfigFileSystemError)(error, pathToDelete);
        throw new HubSpotConfigError_1.HubSpotConfigError(message, type, config_1.HUBSPOT_CONFIG_OPERATIONS.DELETE, {
            cause: error,
        });
    }
}
exports.deleteConfigFileIfEmpty = deleteConfigFileIfEmpty;
function getConfigAccountById(accountId) {
    const { accounts } = getConfig();
    const account = (0, utils_1.getConfigAccountByIdentifier)(accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, accountId);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountById.error', { accountId }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    return account;
}
exports.getConfigAccountById = getConfigAccountById;
function getConfigAccountByName(accountName) {
    const { accounts } = getConfig();
    const account = (0, utils_1.getConfigAccountByIdentifier)(accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, accountName);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountByName.error', { accountName }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    return account;
}
exports.getConfigAccountByName = getConfigAccountByName;
function getConfigAccountIfExists(identifier) {
    const config = getConfig();
    return (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
}
exports.getConfigAccountIfExists = getConfigAccountIfExists;
function getConfigDefaultAccount() {
    const { accounts, defaultAccount } = getConfig();
    let defaultAccountToUse = defaultAccount;
    const currentConfigPath = getConfigFilePath();
    const globalConfigPath = getGlobalConfigFilePath();
    if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
        const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
        defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
    }
    if (!defaultAccountToUse) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigDefaultAccount.fieldMissingError'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.NO_DEFAULT_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    const account = (0, utils_1.getConfigAccountByInferredIdentifier)(accounts, defaultAccountToUse);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigDefaultAccount.accountMissingError', {
            defaultAccountToUse,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    return account;
}
exports.getConfigDefaultAccount = getConfigDefaultAccount;
function getConfigDefaultAccountIfExists() {
    const { accounts, defaultAccount } = getConfig();
    let defaultAccountToUse = defaultAccount;
    // Only check for default account override if we're using the global config
    const currentConfigPath = getConfigFilePath();
    const globalConfigPath = getGlobalConfigFilePath();
    if (currentConfigPath === globalConfigPath && globalConfigFileExists()) {
        const defaultAccountOverrideAccountId = (0, defaultAccountOverride_1.getDefaultAccountOverrideAccountId)();
        defaultAccountToUse = defaultAccountOverrideAccountId || defaultAccount;
    }
    if (!defaultAccountToUse) {
        return;
    }
    const account = (0, utils_1.getConfigAccountByInferredIdentifier)(accounts, defaultAccountToUse);
    return account;
}
exports.getConfigDefaultAccountIfExists = getConfigDefaultAccountIfExists;
function getAllConfigAccounts() {
    const { accounts } = getConfig();
    return accounts;
}
exports.getAllConfigAccounts = getAllConfigAccounts;
function getConfigAccountEnvironment(identifier) {
    const config = getConfig();
    const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.getConfigAccountEnvironment.accountNotFound', {
            identifier,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.READ);
    }
    return (0, environment_1.getValidEnv)(account.env);
}
exports.getConfigAccountEnvironment = getConfigAccountEnvironment;
function addConfigAccount(accountToAdd) {
    if (!(0, utils_1.validateConfigAccount)(accountToAdd)) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.addConfigAccount.invalidAccount'), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    const accountInConfig = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.ACCOUNT_ID, accountToAdd.accountId);
    if (accountInConfig) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.addConfigAccount.duplicateAccount', {
            accountId: accountToAdd.accountId,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    config.accounts.push(accountToAdd);
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.addConfigAccount = addConfigAccount;
function updateConfigAccount(updatedAccount) {
    if (!(0, utils_1.validateConfigAccount)(updatedAccount)) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateConfigAccount.invalidAccount', {
            name: updatedAccount.name,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    const accountIndex = (0, utils_1.getConfigAccountIndexById)(config.accounts, updatedAccount.accountId);
    if (accountIndex < 0) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateConfigAccount.accountNotFound', {
            accountId: updatedAccount.accountId,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    config.accounts[accountIndex] = updatedAccount;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateConfigAccount = updateConfigAccount;
function setConfigAccountAsDefault(identifier) {
    const config = getConfig();
    const account = (0, utils_1.getConfigAccountByInferredIdentifier)(config.accounts, identifier);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.setConfigAccountAsDefault.accountNotFound', {
            identifier,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    config.defaultAccount = account.accountId;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.setConfigAccountAsDefault = setConfigAccountAsDefault;
function renameConfigAccount(currentName, newName) {
    const config = getConfig();
    const account = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, currentName);
    if (!account) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.renameConfigAccount.accountNotFound', {
            currentName,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const duplicateAccount = (0, utils_1.getConfigAccountByIdentifier)(config.accounts, config_1.ACCOUNT_IDENTIFIERS.NAME, newName);
    if (duplicateAccount) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.renameConfigAccount.duplicateAccount', {
            currentName,
            newName,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_ACCOUNT, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    account.name = newName;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.renameConfigAccount = renameConfigAccount;
function removeAccountFromConfig(accountId) {
    const config = getConfig();
    const index = (0, utils_1.getConfigAccountIndexById)(config.accounts, accountId);
    if (index < 0) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.removeAccountFromConfig.accountNotFound', {
            accountId,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.ACCOUNT_NOT_FOUND, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    config.accounts.splice(index, 1);
    if (config.defaultAccount === accountId) {
        delete config.defaultAccount;
    }
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.removeAccountFromConfig = removeAccountFromConfig;
function updateHttpTimeout(timeout) {
    const parsedTimeout = typeof timeout === 'string' ? parseInt(timeout) : timeout;
    if (isNaN(parsedTimeout) || parsedTimeout < config_1.MIN_HTTP_TIMEOUT) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateHttpTimeout.invalidTimeout', {
            minTimeout: config_1.MIN_HTTP_TIMEOUT,
            timeout: parsedTimeout,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    config.httpTimeout = parsedTimeout;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateHttpTimeout = updateHttpTimeout;
function updateAllowUsageTracking(isAllowed) {
    if (typeof isAllowed !== 'boolean') {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAllowUsageTracking.invalidInput', {
            isAllowed: `${isAllowed}`,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    config.allowUsageTracking = isAllowed;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateAllowUsageTracking = updateAllowUsageTracking;
function updateAllowAutoUpdates(isEnabled) {
    if (typeof isEnabled !== 'boolean') {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAllowAutoUpdates.invalidInput', {
            isEnabled: `${isEnabled}`,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    config.allowAutoUpdates = isEnabled;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateAllowAutoUpdates = updateAllowAutoUpdates;
function updateAutoOpenBrowser(isEnabled) {
    if (typeof isEnabled !== 'boolean') {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateAutoOpenBrowser.invalidInput', {
            isEnabled: `${isEnabled}`,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    config.autoOpenBrowser = isEnabled;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateAutoOpenBrowser = updateAutoOpenBrowser;
function updateDefaultCmsPublishMode(cmsPublishMode) {
    if (!cmsPublishMode ||
        !Object.values(files_1.CMS_PUBLISH_MODE).includes(cmsPublishMode)) {
        throw new HubSpotConfigError_1.HubSpotConfigError((0, lang_1.i18n)('config.updateDefaultCmsPublishMode.invalidCmsPublishMode', {
            cmsPublishMode,
        }), config_2.HUBSPOT_CONFIG_ERROR_TYPES.INVALID_FIELD, config_1.HUBSPOT_CONFIG_OPERATIONS.WRITE);
    }
    const config = getConfig();
    config.defaultCmsPublishMode = cmsPublishMode;
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.updateDefaultCmsPublishMode = updateDefaultCmsPublishMode;
function isConfigFlagEnabled(flag, defaultValue) {
    const config = getConfig();
    if (typeof config[flag] === 'undefined') {
        return defaultValue || false;
    }
    return Boolean(config[flag]);
}
exports.isConfigFlagEnabled = isConfigFlagEnabled;
function hasLocalStateFlag(flag) {
    const config = getConfig();
    return config.flags?.includes(flag) || false;
}
exports.hasLocalStateFlag = hasLocalStateFlag;
function addLocalStateFlag(flag) {
    const config = getConfig();
    if (!hasLocalStateFlag(flag)) {
        config.flags = [...(config.flags || []), flag];
    }
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.addLocalStateFlag = addLocalStateFlag;
function removeLocalStateFlag(flag) {
    const config = getConfig();
    config.flags = config.flags?.filter(f => f !== flag) || [];
    (0, utils_1.writeConfigFile)(config, getConfigFilePath());
}
exports.removeLocalStateFlag = removeLocalStateFlag;
